package com.chixing.day16_io.reflect;



import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * A.java ---A.class --- 在JVM Class
 * 通过字节码文件得到该类的结构
 * Student: 成员变量、   构造函数    、       方法      、父类  、接口、注解
 *           (字段 Field) (Constructor)   (Method)    superClass  interface  annotation
 *
 *
 * Method: 修饰符 + 返回值类型 + 方法名 + 参数列表 + 异常
 * 修饰符 modifier ( public+abstract+static+final+native.. )
 */
public class ReflectDemo {
    public static void main(String[] args) {

        Class<Student> clazz = Student.class;

        String className = clazz.getName();
        System.out.println("类名：" + className);
        clazz.getInterfaces();




        Student student = null;
        try {
            student = clazz.newInstance();// 依赖于无参构造函数
            System.out.println("实例化student对象");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        //1. 获得所有的方法 Method
        Method[] methods =  clazz.getDeclaredMethods();

        for(Method method:methods){
            Modifier m;
            int modifier = method.getModifiers();
            String methodName =  method.getName();
            Class<?> returnType =  method.getReturnType();
            Class<?>[] paramTypes = method.getParameterTypes();
            Class<?>[] exceptionTypes = method.getExceptionTypes();

            System.out.print("访问修饰符：" + modifier);
            System.out.print("，方法名称：" + methodName);
            System.out.print("，返回值类型：" + returnType);
            for(Class<?> paramType:paramTypes){
                System.out.print("，参数列表类型：" + paramType);
            }
            System.out.println();
        }

        // (2)方法调用 Object result = stu1.play(10,9.9f)
        Method method = null;
        try {
            method = clazz.getMethod("play",int.class,float.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        // result: return value
        Object result = null;
        try {
            result = method.invoke(student,10,9.9f); // 方法调用（invoke()）
            System.out.println("play方法的返回值：" + result);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


        // (3)方法调用 static study(): Object result = Student.study(...)
        try {
            method = clazz.getMethod("study",int.class,String.class,Float.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            result = method.invoke(Student.class,10,"",9.9f);
            System.out.println("study 方法调用的返回值是：" + result);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}
